#coding=utf-8
#LightCam 文件监控程序
#init by hfh 20151119

import multiprocessing,subprocess,threading
import socket,os,time,re,traceback,sys,binascii
import lc_libs

def genthistime():
	time_struct=time.localtime()
	thistime={}
	thistime['year']=time.strftime('%Y',time_struct)
	thistime['month']=time.strftime('%m',time_struct)
	thistime['day']=time.strftime('%d',time_struct)
	thistime['hour']=time.strftime('%H',time_struct)
	thistime['mintue']=time.strftime('%M',time_struct)
	thistime['second']=time.strftime('%S',time_struct)
	return thistime

def func(this):
	
	#agent_hostname=this['agent_hostname']
	AlertGroup=this['alertgroup']
	filename=this['filename']
	monitortype=this['monitortype']
	interval=this['interval']
	severity=this['severity']
	schedule=this['schedule']
	holiday=this['holiday']
	
	Node=agent_hostname
	#AlertGroup="MonitorLogFile"
	AlertKey=filename+" "+monitortype

	#today=time.strftime('%Y%m%d',time.localtime())
	#filename=filename.replace('YYYYMMDD',today)
	
	thistime=genthistime()
	filename=filename.replace('%Y',thistime['year']).replace('%m',thistime['month']).replace('%d',thistime['day']).replace('%H',thistime['hour']).replace('%M',thistime['mintue']).replace('%S',thistime['second'])
	
	if monitortype=="exist":
		if os.path.exists(filename):
			Severity="1"
			Type="2"
			Summary=agent_hostname+"文件"+filename+"已存在,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"文件"+filename+"不存在告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="noexist":
		if os.path.exists(filename):
			Severity=severity
			Type="1"
			Summary=agent_hostname+"文件"+filename+"存在告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"文件"+filename+"不存在,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="increase":
		flagfile=lchome+'/flag/stdfile__increase__'+filename.replace('/','_')
		nsize=os.path.getsize(filename)
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(str(nsize))
			fc.close()
			fc=open(flagfile,'r+')
		pointer=int(fc.read())
		fc.seek(0,0)
		fc.truncate()
		fc.write(str(nsize))
		fc.close()
		if nsize > pointer:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内已增长,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内未增长告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="decrease":
		flagfile=lchome+'/flag/stdfile__decrease__'+filename.replace('/','_')
		nsize=os.path.getsize(filename)
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(str(nsize))
			fc.close()
			fc=open(flagfile,'r+')
		pointer=int(fc.read())
		fc.seek(0,0)
		fc.truncate()
		fc.write(str(nsize))
		fc.close()
		if nsize < pointer:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内已变小,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内未变小告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="unchange":
		flagfile=lchome+'/flag/stdfile__unchange__'+filename.replace('/','_')
		nfile=str(binascii.crc32(open(filename,'rb').read()))
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(nfile)
			fc.close()
			fc=open(flagfile,'r+')
		cfile=fc.read()
		fc.seek(0,0)
		fc.truncate()
		fc.write(nfile)
		fc.close()
		if cfile == nfile:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内内容无变化,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内内容变化告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="change":
		flagfile=lchome+'/flag/stdfile__change__'+filename.replace('/','_')
		nfile=str(binascii.crc32(open(filename,'rb').read()))
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(nfile)
			fc.close()
			fc=open(flagfile,'r+')
		cfile=fc.read()
		fc.seek(0,0)
		fc.truncate()
		fc.write(nfile)
		fc.close()
		if cfile != nfile:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内内容变化,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内内容无变化告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="prounchange":
		flagfile=lchome+'/flag/stdfile__prounchange__'+filename.replace('/','_')
		nfile=os.stat(filename)
		npro="st_mode=%s, st_ino=%s, st_dev=%s, st_nlink=%s, st_uid=%s, st_gid=%s, st_size=%s, st_atime=%s, st_mtime=%s, st_ctime=%s" % (nfile.st_mode, nfile.st_ino, nfile.st_dev, nfile.st_nlink, nfile.st_uid, nfile.st_gid, nfile.st_size, nfile.st_atime, nfile.st_mtime, nfile.st_ctime)
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(npro)
			fc.close()
			fc=open(flagfile,'r+')
		cpro=fc.read()
		fc.seek(0,0)
		fc.truncate()
		fc.write(npro)
		fc.close()
		if cpro == npro:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内属性无变化,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内属性变化告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="prochange":
		flagfile=lchome+'/flag/stdfile__prochange__'+filename.replace('/','_')
		nfile=os.stat(filename)
		npro="st_mode=%s, st_ino=%s, st_dev=%s, st_nlink=%s, st_uid=%s, st_gid=%s, st_size=%s, st_atime=%s, st_mtime=%s, st_ctime=%s" % (nfile.st_mode, nfile.st_ino, nfile.st_dev, nfile.st_nlink, nfile.st_uid, nfile.st_gid, nfile.st_size, nfile.st_atime, nfile.st_mtime, nfile.st_ctime)
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(npro)
			fc.close()
			fc=open(flagfile,'r+')
		cpro=fc.read()
		fc.seek(0,0)
		fc.truncate()
		fc.write(npro)
		fc.close()
		if cpro <> npro:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内属性变化,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"文件"+filename+" "+str(interval)+"秒内属性无变化告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="confprounchange":
		flagfile=lchome+'/flag/stdfile__confprounchange__'+filename.replace('/','_')
		nfile=os.stat(filename)
		npro="st_mode=%s, st_ino=%s, st_dev=%s, st_nlink=%s, st_uid=%s, st_gid=%s, st_size=%s, st_atime=%s, st_mtime=%s, st_ctime=%s" % (nfile.st_mode, nfile.st_ino, nfile.st_dev, nfile.st_nlink, nfile.st_uid, nfile.st_gid, nfile.st_size, nfile.st_atime, nfile.st_mtime, nfile.st_ctime)
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(npro)
			fc.close()
			fc=open(flagfile,'r+')
		cpro=fc.read()
		fc.close()
		if cpro == npro:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"配置文件"+filename+"属性无变化,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"配置文件"+filename+"属性变化告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="confprochange":
		flagfile=lchome+'/flag/stdfile__confprochange__'+filename.replace('/','_')
		nfile=os.stat(filename)
		npro="st_mode=%s, st_ino=%s, st_dev=%s, st_nlink=%s, st_uid=%s, st_gid=%s, st_size=%s, st_atime=%s, st_mtime=%s, st_ctime=%s" % (nfile.st_mode, nfile.st_ino, nfile.st_dev, nfile.st_nlink, nfile.st_uid, nfile.st_gid, nfile.st_size, nfile.st_atime, nfile.st_mtime, nfile.st_ctime)
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(npro)
			fc.close()
			fc=open(flagfile,'r+')
		cpro=fc.read()
		fc.close()
		if cpro <> npro:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"配置文件"+filename+"属性变化,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"配置文件"+filename+"属性无变化告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="confunchange":
		flagfile=lchome+'/flag/stdfile__confunchange__'+filename.replace('/','_')
		nfile=open(filename,'rb').read()
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(nfile)
			fc.close()
			fc=open(flagfile,'r+')
		cfile=fc.read()
		fc.close()
		if cfile == nfile:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"配置文件"+filename+"无变化,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"配置文件"+filename+"变化告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	elif monitortype=="confchange":
		flagfile=lchome+'/flag/stdfile__confchange__'+filename.replace('/','_')
		nfile=open(filename,'rb').read()
		try:
			fc=open(flagfile,'r+')
		except IOError:
			fc=open(flagfile,'w')
			fc.write(nfile)
			fc.close()
			fc=open(flagfile,'r+')
		cfile=fc.read()
		fc.close()
		if cfile != nfile:
			Severity="1"
			Type="2"
			Summary=agent_hostname+"配置文件"+filename+"变化,事件恢复"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
		else:
			Severity=severity
			Type="1"
			Summary=agent_hostname+"配置文件"+filename+"无变化告警"
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
	else:
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" can not support this MonitorType: "+monitortype+" \n" )
		logfile.flush()
		return 0

if __name__ == "__main__":

	lchome=lc_libs.lc_getlchome()
	scname=sys.argv[0].split('.')[0]
	logfilename=lchome+'/log/'+scname+'.log'
	confname=lchome+'/conf/'+scname+'.conf'
	
	today=time.strftime('%Y%m%d',time.localtime())
	os.system("mv %s %s.%s" % (logfilename,logfilename,today))
	
	logfile=file(logfilename,'a')
	logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
	logfile.write(logdate+" Started.\n")
	logfile.flush()
	
	agent_hostname=lc_libs.lc_gethostname()
	
	#初始化events数据库
	#dbfile="../db/lc_events.db"
	#tablename="lc_events"
	#tablefield="Node varchar(32),AlertGroup varchar(64),AlertKey varchar(64),Severity varchar(8),Type varchar(8),LastOccurrence varchar(32),Summary varchar(256)"
	#db=lc_libs.lc_dboperater(dbfile,tablename,tablefield)
	#db.create_db()
	#db.close_db()

	try:
		#初始化数据库
		db=lc_libs.lc_mongodb_operater('127.0.0.1',27017)

		db.connect()
		Conn=db.getConn()
		if Conn==None:
			print "Can not Connect to the MondbDB"
			exit(0)
		
		events_dbname='lc_events'
		events_tablename='lc_events'
		
		history_dbname='lc_history'
		history_tablename="lc_stdfile"
		
		events_db=db.useDatabase(events_dbname)
		events_table=db.UseCollection(events_db,events_tablename)
		
		history_db=db.useDatabase(history_dbname)
		history_table=db.UseCollection(history_db,history_tablename)

	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" 初始化数据库失败:\n"+excinfo+"\n")
		logfile.flush()
		exit(0)


	MonitorList = []
	
	for lines in open(confname):
		#if line[0] == '#' or agent_hostname != line.split("\t")[0]:
		if lines[0] == '#' or lines.split("\t")[0] not in (agent_hostname,'default'):
			continue

		line=lines.strip('\r\n').split('\t')
		dconf={}
		
		#dconf['agent_hostname']=line[0]
		dconf['alertgroup']=line[1]
		dconf['filename']=line[2]
		dconf['monitortype']=line[3]
		dconf['interval']=line[4]
		dconf['severity']=line[5]
		dconf['schedule']=line[6]
		dconf['holiday']=line[7]

		flagfile=lchome+'/flag/stdfile__'+dconf['filename'].replace('/','_')
		os.system("rm -f "+flagfile)
		
		MonitorList.append(dconf)

	usedtime=0
	
	while True:
		time.sleep(1)
		realtime=int(time.time())
		
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		holiday_state = lc_libs.lc_isholiday()
		
		threads = []
		for i in MonitorList:
			if int(i['holiday']) == 1 and holiday_state == True:
				continue
				
			time_state = lc_libs.lc_schedule(i['schedule'])
			if time_state == False:
				continue
			
			flag=realtime%int(i['interval'])
			#print flag
			if flag<=usedtime:
				#print i
				t = threading.Thread(target=func,args=(i,))
				threads.append(t)
		
		for t in threads:
			t.start()
			while True:
				#print len(threading.enumerate())
				time.sleep(0.01)
				if(len(threading.enumerate()) < 100):
					break

		#排除执行程序导致的时间差
		usedtime=int(time.time())-realtime
		#print "usedtime:%s" % usedtime
